/**
 * Copyright (C) 2011 The Android Open Source Project 
 * Emial : guoyil199@163.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

/**
 * <pre>
 * 由于常见的单例模式,饿汉式单例和懒汉式单例,构造方法都私有了,因此不能被继承.
 * 最近在开发中遇到问题了,恰好需要继承单例类.找资料才找到了这个解决办法---登记式单例.
 * 登记式单例类是为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的
 * </pre>
 */
// 登记式单例类

public class RegSingleton {
	static private HashMap m_registry = new HashMap();
	private List<String> plsyers = new LinkedList<String>();

	static {
		RegSingleton x = new RegSingleton();
		m_registry.put(x.getClass().getName(), x);
	}

	/**
	 * 保护的默认构造子
	 */
	protected RegSingleton() {
	}

	/**
	 * 静态工厂方法，返还此类惟一的实例
	 */
	static public RegSingleton getInstance(String name) {
		if (name == null) {
			name = "com.RegSingleton";
		}
		if (m_registry.get(name) == null) {
			try {
				m_registry.put(name, Class.forName(name).newInstance());
			} catch (Exception e) {
				System.out.println("Error happened.");
			}
		}
		return (RegSingleton) (m_registry.get(name));
	}

	public void remove(String player) {
		plsyers.remove(player);
	}

	public List<String> getPlayers() {
		return plsyers;
	}
}

// 它的子类RegSingletonChild 需要父类的帮助才能实例化。下图所示是登记式单例类子类的一个例子。图中的关系表明，此类是由父类将子类实例化的。
// 下面是子类的源代码。

class RegSingletonChild extends RegSingleton {
	public RegSingletonChild() {
	}

	/**
	 * 静态工厂方法
	 */
	static public RegSingletonChild getInstance() {
		return (RegSingletonChild) RegSingleton
				.getInstance("com.RegSingletonChild");
	}

	public void test() {
		int a = getPlayers().size();
		int b = RegSingleton.getInstance("").getPlayers().size();
	}
}
